
#include "app.h"
#include "audio_es7210.h"
#include <memory>
#include "sd_card.h"
#include <lwip/def.h>


void App::print_all_tasks() {
    char task_list_buffer[1024]; // 缓冲区大小建议 >= 512 字节
    vTaskList(task_list_buffer); // 获取任务信息
    printf("Task List:\n%s\n", task_list_buffer);
} 


App::App(){
    
    work_task = new WorkTask(4096*8);
opus_encoder_ = std::make_unique<OpusEncoderWrapper>(16000, 1, 60);
audio_input_ = std::make_unique<AudioEs7210>(16000, 1);
file_ = std::make_unique<SdCard>(); 

}

App::~App(){


}

void App::run(){ 
    

   //打开文件
    ESP_ERROR_CHECK(file_->open("test.opus","wb")); 
    std::printf("开始说话\n");
    //启动录音
    audio_input_->enable();
    vTaskDelay(pdMS_TO_TICKS(1000));    

    //录音50帧，每帧60ms,总共3秒
    for (size_t i = 0; i < 50; i++)
    {
        
        std::printf("录音第 %d 帧\n",num);
        // 创建动态数组，用于存储录音数据（频繁在堆内存分配空间造成内存碎片）
        std::vector<int16_t> pcm(960);
        // 读取录音数据(注意这里面传入的读取数据大小是字节数，所以要*sizeof(int16_t))
        audio_input_->read(pcm.data(), pcm.size()*sizeof(int16_t), nullptr);

        // 提交任务到后台线程执行，用于编码
        work_task->add_task([this,pcm = std::move(pcm)]() mutable {  
            
            opus_encoder_->Encode(std::move(pcm),[this](std::vector<uint8_t>&& opus){ 
                // 1. 计算帧长度（4字节大端序）
                uint32_t frame_size = static_cast<uint32_t>(opus.size());
                // 2、转为大端序
                uint32_t frame_size_big_endian = htonl(frame_size); // 转为大端序

                // 3. 先写入帧长度（4字节）
                file_->write_file(reinterpret_cast<const char*>(&frame_size_big_endian), sizeof(frame_size_big_endian));

                // 4. 再写入编码后的数据
                file_->write_file(reinterpret_cast<const char*>(opus.data()), opus.size());
                
            });
        });
    }
    //延时（必要，等待后台任务执行完成）
    vTaskDelay(pdMS_TO_TICKS(1000));    
    audio_input_->disable();
    std::printf("结束说话\n");
    file_->close();


    while (true)
    {
        vTaskDelay(pdMS_TO_TICKS(1000));    
        print_all_tasks();     
    }
}